#include "function.h"
#include <QDebug>
#include <QRegularExpression>
#include <QThread>
#include <QTime>

//static QList<QList<QString>> IP_PORT_KIND;

Function::Function(QObject *parent) : QObject(parent)
{
    hashFunc.insert("00",(P_FUNC)&Function::function00);
    hashFunc.insert("01",(P_FUNC)&Function::function01);
    hashFunc.insert("02",(P_FUNC)&Function::function02);
    hashFunc.insert("03",(P_FUNC)&Function::function03);
    hashFunc.insert("04",(P_FUNC)&Function::function04);
    hashFunc.insert("05",(P_FUNC)&Function::function05);
    hashFunc.insert("06",(P_FUNC)&Function::function06);
    hashFunc.insert("07",(P_FUNC)&Function::function07);


    hashFunc.insert("21",(P_FUNC)&Function::function21);
    hashFunc.insert("22",(P_FUNC)&Function::function22);
    hashFunc.insert("23",(P_FUNC)&Function::function23);
    hashFunc.insert("24",(P_FUNC)&Function::function24);
    hashFunc.insert("99",(P_FUNC)&Function::function99);
}

QString Function::callFuncByKey(QString key, MsgDatagram &msg)
{
    if (hashFunc.contains(key))
    {
        P_FUNC ptrFunc = hashFunc.value(key);
        return (this->*ptrFunc)(msg);
    }
    //else
    //msg.m_pressureData.valueList = QJsonArray();
    return QString();
}

QString Function::handle(MsgDatagram &msg)
{
    return this->callFuncByKey(msg.function,msg);
}

QString Function::function00(MsgDatagram &msg)
{
    if(DBManager::getInstance().logon(msg))
      return QString("7E7E;kind:server;function:00;logStatus:true;reason:用户注册成功;");
    else
      return QString("7E7E;kind:server;function:00;logStatus:false;reason:用户已注册;");
}



QString Function::function01(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function01 msg:"<<msg;
    msg.m_source = CEnum::MSG_SOURCE::SERVER;
    msg.m_errorReason = "userError";
    QString loginStr;
    //验证用户账号和密码是否正确
    DBManager::getInstance().checkLogin(msg);
    QString logStatus = msg.m_logStatus? "true":"false";
    loginStr = QString("7E7E;kind:server;function:01;logStatus:%1;reason:%2;").arg(logStatus).arg(msg.m_errorReason);
    qDebug()<<"返回登陆信息:"<<loginStr<<endl;
    return loginStr;

}

//病人排队信息
QString Function::function02(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function02 msg:"<<msg;
    msg.m_source = CEnum::MSG_SOURCE::SERVER;
    QString f02Result = QString("7E7E;kind:server;function:02;phone:%1;pass:%2;medicalKind:").arg(msg.m_user.phoneNum).arg(msg.m_user.password);
    QString medicalKind;
    QMap<QString,int> serverTypeCount_map = DBManager::getInstance().findOperationTypeCount();
    foreach(const QString key,serverTypeCount_map.keys())
    {
        int orderNum = DBManager::getInstance().findOrderNum(key,msg.m_user.phoneNum);
        if(orderNum==0)
            medicalKind += QString("[name(%1),currentLine(%2),isLine(false)],").arg(key).arg(QString::number(serverTypeCount_map.value(key)));
        else //有当前预约医疗服务
            medicalKind += QString("[name(%1),currentLine(%2),isLine(true)],number(%3),").arg(key).arg(QString::number(serverTypeCount_map.value(key)-1)).arg(QString::number(orderNum));


    }
    if(!medicalKind.isEmpty())
        medicalKind.replace(medicalKind.length()-1,1,';');
    f02Result+=medicalKind;
    qDebug()<<"病人排队信息:"<<f02Result<<endl;
    return f02Result;

//    QList<QList<QString>> row;QString reservaOp;
//    QString rsql = QString("SELECT reservaOperation FROM user WHERE phonenum = %1").arg(msg.m_user.phoneNum);
//    if(bSqlite->find(rsql,&row)&&(!row.isEmpty()))
//        reservaOp = row.at(0).at(0);  //病人预约的手术
//    QString sql = "SELECT *FROM queueinformation";
//    QList<QList<QString>> rows;
//    if(bSqlite->find(sql,&rows)&&(!rows.isEmpty()))
//    {
//        QString f02Result = msg.m_Head + QString(";kind:")+ CEnum::enumtoString(msg.m_source)+QString(";function:")
//                           +msg.function + QString(";phone:")+msg.m_user.phoneNum+QString(";pass:")+msg.m_user.password
//                           +QString(";medicalKind:");
//        QString medicalKind;
//        for(int i=0;i<rows.size();i++)
//        {
//            if(rows.at(i).at(1) == reservaOp)
//            {
//                msg.m_opeLineInfo.operation_line_count = rows.at(i).at(2).toInt();//this->findm_opeLineInfo.operation_line_count(rows.at(i).at(1));
//                medicalKind += QString("[")
//                +QString("name(%1),currentLine(%2),isLine(true),number(%3)").arg(rows.at(i).at(1)).arg(msg.m_opeLineInfo.operation_line_count).arg(msg.m_opeLineInfo.operation_line_count+1)
//                +QString("],");
//            }
//            else
//            {
//                msg.m_opeLineInfo.operation_line_count = msg.m_opeLineInfo.operation_line_count = rows.at(i).at(2).toInt();//this->findm_opeLineInfo.operation_line_count(rows.at(i).at(1));
//                medicalKind += QString("[")
//                +QString("name(%1),currentLine(%2),isLine(false)").arg(rows.at(i).at(1)).arg(msg.m_opeLineInfo.operation_line_count)
//                +QString("],");
//            }
//        }

//        if(!medicalKind.isEmpty() && medicalKind.at(medicalKind.length()-1) == ',')
//            medicalKind.replace(medicalKind.length()-1,1,";");
//        f02Result+=medicalKind;
//        return f02Result;
//    }
//    else
//    {
//        qDebug()<<"排队数据获取失败！！！"<<endl;
//        return QString();
//    }



}

//手术（取消）预约
QString Function::function03(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function03 msg:"<<msg;
    msg.m_source = CEnum::MSG_SOURCE::SERVER;
    msg.m_opeLineInfo.operation_type = this->cutOutOperationType(msg.choose);
    msg.m_opeLineInfo.operation_line_count = DBManager::getInstance().findOperationTypeCount(msg.m_opeLineInfo.operation_type);
//    msg.m_opeLineInfo.operation_line_num = msg.m_opeLineInfo.operation_line_count+1;
    QString f03Result;

    //预约
    if(msg.choose.contains("true"))
    {
        if(DBManager::getInstance().appointment(msg))
        {
             f03Result = msg.m_Head + QString(";kind:server;function:03;phone:")+msg.m_user.phoneNum
                               +QString(";pass:")+msg.m_user.password+QString(";choose:")+QString("%1(true),").arg(msg.m_opeLineInfo.operation_type)
                               +QString("number(%1),").arg(QString::number(msg.m_opeLineInfo.operation_line_num))
                               +QString("currentLine(%1);").arg(QString::number(msg.m_opeLineInfo.operation_line_count));
        }
        if(msg.m_opeLineInfo.operation_type=="泌尿外科手术")
        {//给设备发送

            QString sql = QString("SELECT *FROM patientInformation WHERE phonenum = '%1'; ").arg(msg.m_user.phoneNum);
            this->findPatientInformation(msg,sql);
            QString resultStr = QString("7E7E;kind:surgery;function:02;currentPack:1;sumPack:1;people:[name:%1,sex:%2,phone:%3,nation:%4,birth:%5,age:%6,number:%7,id:%8,blood:%9型血,illness:%10,irritability:%11];")
                    .arg(msg.m_patientInfo.p_name).arg(msg.m_patientInfo.p_sex).arg(msg.m_patientInfo.p_phonenum)
                    .arg(msg.m_patientInfo.p_nation).arg(msg.m_patientInfo.p_birthday).arg(msg.m_patientInfo.p_age).arg(QString::number(DBManager::getInstance().findOrderNum("泌尿外科手术",msg.m_patientInfo.p_phonenum))).arg(msg.m_patientInfo.p_ID)
                    .arg(CEnum::enumtoString (msg.m_patientInfo.p_bloodtype)).arg(msg.m_patientInfo.p_diseaseHistory).arg(msg.m_patientInfo.p_drugAllergyHistory);

            emit sendDevice(resultStr);
            qDebug()<<"预约信号发送！！！"<<endl;
        }

        qDebug()<<"预约返回信息："<<f03Result<<endl;

    }
    //取消预约
    if(msg.choose.contains("false"))
    {//给设备发送
        if(DBManager::getInstance().cancelappointment(msg))
        {
            //msg.m_opeLineInfo.operation_line_count = DBManager::getInstance().findOperationTypeCount(msg.m_opeLineInfo.operation_type);
            f03Result = QString("7E7E;kind:server;function:03;phone:%1;pass:%2;choose:%3(true),number(%4),currentLine(%5);").arg(msg.m_user.phoneNum).arg(msg.m_user.password)
                        .arg(msg.m_opeLineInfo.operation_type).arg("").arg(QString::number(msg.m_opeLineInfo.operation_line_count-1));
        }
        //发送设备端取消预约
        if(msg.m_opeLineInfo.operation_type=="泌尿外科手术")
        {
            QString resultStr = QString("7E7E;kind:server;function:05;choose:泌尿外科手术;name:%1;phone:%2;").arg(DBManager::getInstance().findPatientName(msg.m_user.phoneNum)).arg(msg.m_user.phoneNum);
            emit sendDevice(resultStr);
            qDebug()<<"取消预约信号发送！！！"<<endl;
        }


        qDebug()<<"取消预约返回信息："<<f03Result<<endl;

    }

   return f03Result;
}


QString Function::function04(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function04 msg:"<<msg;
    msg.m_source = CEnum::MSG_SOURCE::SERVER;
    QList<QList<QString>> rows;
    QString sql = QString("SELECT *FROM patientInformation WHERE phonenum = %1").arg(msg.m_user.phoneNum);
    if(bSqlite->find(sql,&rows)&&(!rows.isEmpty()))
    {
       msg.m_source = CEnum::MSG_SOURCE::SERVER;
       msg.m_user.username = rows.at(0).at(1);
       msg.m_patientInfo.p_age = rows.at(0).at(2).toInt();
       msg.m_patientInfo.p_sex = rows.at(0).at(3);
       msg.m_patientInfo.p_nation = rows.at(0).at(4);
       msg.m_patientInfo.p_bloodtype = CEnum::stringToEnum<CEnum::PATIENT_BLOOD_TYPE> (rows.at(0).at(5));
       msg.m_patientInfo.p_birthday = rows.at(0).at(6);
       msg.m_patientInfo.p_ID = rows.at(0).at(7);  //身份证号
       msg.m_patientInfo.p_phonenum = rows.at(0).at(8);
       msg.m_patientInfo.p_diseaseHistory = rows.at(0).at(9);
       msg.m_patientInfo.p_drugAllergyHistory = rows.at(0).at(10);
       QString f04Result = msg.m_Head + QString(";kind:")+ CEnum::enumtoString(msg.m_source).toLower()+QString(";function:")
               +msg.function + QString(";phone:")+msg.m_patientInfo.p_phonenum+QString(";pass:")+msg.m_user.password
               +QString(";name:")+msg.m_user.username+QString(";sex:")+msg.m_patientInfo.p_sex
               + QString(";phone:")+msg.m_patientInfo.p_phonenum+QString(";nation:")+msg.m_patientInfo.p_nation
               +QString(";birth:")+msg.m_patientInfo.p_birthday+QString(";age:")+QString::number(msg.m_patientInfo.p_age)
               +QString(";id:")+msg.m_patientInfo.p_ID+QString(";blood:")+CEnum::enumtoString(msg.m_patientInfo.p_bloodtype)+QString("型血")+
               QString(";illness:")+msg.m_patientInfo.p_diseaseHistory+QString(";irritability:")+msg.m_patientInfo.p_drugAllergyHistory+QString(";");
       return f04Result;
    }
    else
    {
        qDebug()<<"基本信息查询失败！！！"<<endl;
        return QString();
    }

}


//修改病人基本信息
QString Function::function05(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function05 msg:"<<msg;
    if(DBManager::getInstance().updatePatientInfo(msg))
        return QString("7E7E;kind:server;function:05;phone:%1;pass:%2;status:true;").arg(msg.m_user.phoneNum).arg(msg.m_user.password);
    else {
        return QString("7E7E;kind:server;function:05;phone:%1;pass:%2;status:false;").arg(msg.m_user.phoneNum).arg(msg.m_user.password);
        qDebug()<<"修改病人信息失败！！！"<<endl;
    }
}

//修改密码
QString Function::function06(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function06 msg:"<<msg;
    QString sql = QString("UPDATE user SET password='%1' WHERE phonenum = '%2';").arg(msg.m_user.newPassword).arg(msg.m_user.phoneNum);

    if(bSqlite->update(sql))
    {
        if(DBManager::getInstance().findUserPassword(msg))
            return QString("7E7E;kind:server;function:05;phone:%1;pass:%2;status:true;").arg(msg.m_user.phoneNum).arg(msg.m_user.password);

    }
    else
        return QString("7E7E;kind:server;function:05;phone:%1;pass:%2;status:false;").arg(msg.m_user.phoneNum).arg(msg.m_user.password);

}

QString Function::function07(MsgDatagram &msg)
{
   QString isOrder = DBManager::getInstance().findOrderNum(msg.m_user.phoneNum)!=0? "true":"false";
   return QString("7E7E;kind:phone;function:07;phone:%1;pass:%2;isHave:%3;").arg(msg.m_user.phoneNum).arg(msg.m_user.password).arg(isOrder);
}

QString Function::function21(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function05 msg:"<<msg;
    msg.function = "01";
    msg.m_logStatus = true;
    QString f05Result = msg.m_Head + QString(";kind:")+CEnum::enumtoString(msg.m_source).toLower()+ QString(";function:") +msg.function
                       +QString(";logStatus:")+  QString(msg.m_logStatus? "true":"false")+QString(";");
    return f05Result;

}

//设备查询病人预约（泌尿外科手术）信息
QString Function::function22(MsgDatagram &msg)
{
#define TOTALPACK 1
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function06 msg:"<<msg;
    //设备预约手术病人的信息
    QString f06Result = QString("7E7E;kind:surgery;function:02;currentPack:1;sumPack:%1;people:").arg(QString::number(TOTALPACK));
    QList<QList<QString>> userList; //保存预约手术的病人手机号
    QString sql1 = "SELECT *FROM patienorder WHERE operationType = '泌尿外科手术';";
    QString sql = "SELECT *FROM patientInformation WHERE phonenum IN (";

    if(bSqlite->find(sql1,&userList)&&(!userList.isEmpty()))
    {
        for(int i=0;i<userList.size();i++)
        {
            sql+=(QString("'%1',").arg(userList.at(i).at(0)));
        }
        if(sql.at(sql.length()-1)==',')
            sql.remove(sql.length()-1,1);
        sql+=QString(")");
    }

    QList<QList<QString>> rows;
    if(bSqlite->find(sql,&rows)&&(!rows.isEmpty()))
    {
      for(int i=0;i<rows.size();i++)
      {
          msg.m_user.username = rows.at(i).at(1);
          msg.m_patientInfo.p_age = rows.at(i).at(2).toInt();
          msg.m_patientInfo.p_sex = rows.at(i).at(3);
          msg.m_patientInfo.p_nation = rows.at(i).at(4);
          msg.m_patientInfo.p_bloodtype = CEnum::stringToEnum<CEnum::PATIENT_BLOOD_TYPE>(rows.at(i).at(5));
          msg.m_patientInfo.p_birthday = rows.at(i).at(6);
          msg.m_patientInfo.p_ID = rows.at(i).at(7);  //身份证号
          msg.m_patientInfo.p_phonenum = rows.at(i).at(8);
          msg.m_patientInfo.p_diseaseHistory = rows.at(i).at(9); //遗传病史
          msg.m_patientInfo.p_drugAllergyHistory = rows.at(i).at(10); //过敏史
          f06Result+=QString("[name:%1,sex:%2,phone:%3,nation:%4,birth:%5,age:%6,number:%7,id:%8,blood:%9,illness:%10,irritability:%11],")
                  .arg(msg.m_user.username).arg(msg.m_patientInfo.p_sex).arg(msg.m_patientInfo.p_phonenum).arg(msg.m_patientInfo.p_nation).arg(msg.m_patientInfo.p_birthday)
                  .arg(msg.m_patientInfo.p_age).arg(QString::number(this->findReservaNum(msg.m_patientInfo.p_phonenum))).arg(msg.m_patientInfo.p_ID).arg(CEnum::enumtoString(msg.m_patientInfo.p_bloodtype).toUpper()+QString("型血")).arg(msg.m_patientInfo.p_diseaseHistory).arg(msg.m_patientInfo.p_drugAllergyHistory);
      }
          if(f06Result.at(f06Result.length()-1) == ',')
              f06Result.replace(f06Result.length()-1,1,";");
    }
    else
        qDebug()<<"传给设备病人信息失败"<<endl;
    return f06Result;

}

//设备端数据处理之
QString Function::function23(MsgDatagram &msg)
{
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function07 msg:"<<msg;
    msg.m_pressureData.value.prepend(")");
    QMap<QString, QList<QString>> dataMap;
    QList<QString> valueList,collectNumberList,timestampList;

    QRegularExpression reg1("(?<=\\)).*?(?=\\()");
    QRegularExpressionMatchIterator iterKey = reg1.globalMatch(msg.m_pressureData.value);
    QRegularExpression reg2("(?<=\\().*?(?=\\))");
    QRegularExpressionMatchIterator iterValue = reg2.globalMatch(msg.m_pressureData.value);
    while (iterKey.hasNext() && iterValue.hasNext())
    {
        valueList.append(iterValue.next().captured(0));
        collectNumberList.append(msg.m_pressureData.collect_num);
        timestampList.append(QString("%1").arg(iterKey.next().captured(0)));
    }

    dataMap.insert("value",valueList);
    dataMap.insert("collectNumber",collectNumberList);
    dataMap.insert("timestamp",timestampList);
    bSqlite->add("metadata",dataMap);

//    foreach (QString key, dataMap.keys()) {
//       qDebug() << key << ":" << dataMap.value(key);
//    }
    return QString();

}

QString Function::function24(MsgDatagram &msg)
{
    msg.m_opeLineInfo.operation_type = "泌尿外科手术";
    if(DBManager::getInstance().cancelappointment(msg))
    {
        qDebug()<<"删除病人预约信息成功"<<endl;
    }
    return QString();  //无需向设备端返回删除病人信息

}

QString Function::function99(MsgDatagram &msg)
{

//    QList<QString> list;
//    list.append(msg.ip);
//    list.append(QString::number(msg.port));
//    list.append(CEnum::enumtoString(msg.m_source));
//    IP_PORT_KIND.append(list);
    qDebug()<<__FILE__<<", "<<__FUNCTION__<<" current thread:"<<QThread::currentThread()<<endl;
    qDebug()<<"function99 msg:"<<msg;
    this->flag = CEnum::enumtoString(msg.m_source).toLower();
    return QString();

}

bool Function::checkUserInfo(QString phoneNum, QString password)
{
    qDebug()<<"phoneNum:"<<phoneNum<<" "<<"password"<<password<<endl;
    QString sql = QString("SELECT password FROM user WHERE phonenum = %1").arg(phoneNum);
    QList<QList<QString>> row;
    if(bSqlite->find(sql,&row)&&(!row.isEmpty()))
    {
        qDebug()<<"查询用户密码:"<<row.at(0).at(0)<<endl;
        if(row.at(0).at(0)!=password)
            qDebug()<<"用户密码错误"<<endl;
        else
            return true;
    }
    else{
        qDebug()<<"用户信息查询失败"<<endl;
        return false;
    }
    return true;
}

QString Function::cutOutOperationType(QString choose)
{
    qDebug()<<"手术类型提取choose:"<<choose<<endl;
    QRegularExpression reg(".*?(?=\\()");
    QRegularExpressionMatch regMatch = reg.match(choose);
    if(regMatch.hasMatch())
        return regMatch.captured();
    else
        qDebug()<<"手术类型未提取成功！！！"<<endl;
        return QString();
}

int Function::findMaxreservaNum()
{
    QList<QList<QString>> rows;
    QString sql("SELECT max(reservaNum) as max_value  FROM user");
    if(bSqlite->find(sql,&rows)&&(!rows.isEmpty()))
        return rows.at(0).at(0).toInt();
    else
        qDebug()<<"没有找到最大的排队号"<<endl;

}

int Function::findOperationQueueCount(QString operationType)
{
    QList<QList<QString>> rows;
    QString sql = QString("SELECT count(*) FROM user WHERE reservaOperation = '%1';").arg(operationType);
    qDebug()<<operationType<<"当前排队人数sql语句:"<<sql<<endl;
    if(bSqlite->find(sql,&rows)&&(!rows.isEmpty()))
    {
        qDebug()<<operationType<<"当前排队人数:"<<rows.at(0).at(0)<<endl;
        return rows.at(0).at(0).toInt();
    }
    else
        qDebug()<<"没有找到"<<operationType<<"当前排队人数"<<endl;
    return 0;
}

//根据手机号查找user表中病人的排队号
int Function::findReservaNum(QString phoneNum)
{
    QList<QList<QString>> rows;
    QString sql = QString("SELECT orderNum FROM patienorder WHERE operationType = '泌尿外科手术' AND phonenum = '%1';").arg(phoneNum);
    if(bSqlite->find(sql,&rows)&&(!rows.isEmpty()))
        return rows.at(0).at(0).toInt();
    else
        qDebug()<<"没有找到"<<phoneNum<<"的排队号"<<endl;
}



bool Function::findPatientInformation(MsgDatagram &msg, QString sql)
{
    QList<QList<QString>> rows;
    if(bSqlite->find(sql,&rows)&&(!rows.isEmpty()))
    {
       msg.m_source = CEnum::MSG_SOURCE::SERVER;
       msg.m_patientInfo.p_name = rows.at(0).at(1);
       msg.m_patientInfo.p_age = rows.at(0).at(2).toInt();
       msg.m_patientInfo.p_sex = rows.at(0).at(3);
       msg.m_patientInfo.p_nation = rows.at(0).at(4);
       msg.m_patientInfo.p_bloodtype = CEnum::stringToEnum<CEnum::PATIENT_BLOOD_TYPE>(rows.at(0).at(5));
       msg.m_patientInfo.p_birthday = rows.at(0).at(6);
       msg.m_patientInfo.p_ID = rows.at(0).at(7);  //身份证号
       msg.m_patientInfo.p_phonenum = rows.at(0).at(8);
       msg.m_patientInfo.p_diseaseHistory = rows.at(0).at(9);
       msg.m_patientInfo.p_drugAllergyHistory = rows.at(0).at(10);
       return true;
    }
    qDebug()<<"未找到病人信息！！！"<<endl;
    return false;
}
